perm filename M11C.F4[M11,LCS]4 blob sn#411142 filedate 1979-01-15 generic text, type T, neo UTF8
00100	CFORS3     FORTRAN UNIT GENERATOR ROUTINE     
00200	C    *** MUSIC V ***     
00300	      SUBROUTINE FORSAM   
00400		DIMENSION ENVP(27),COSP(27)
00500	C COSP & ENVP STORE POINTERS FOR 'COS' & 'ENV' ARRAYS. SEE AT 105 FOR INFO.
00600		COMMON /LM/L(10),M(10),NSAMX
00700	C CAN USE UP TO 10 FIELDS IN UNIT GEN.
00800	      COMMON I(1) /P/P(1) /GENS/GENS(1) /LFUNC/LFUNC,XNFUN,PINCR
00900		1 /XIN/AMP,FREQ
01000		COMMON /INS/INS(1) /NT/RNT(1) /ROUT/ROUT(1)
01100	C  INS=INSTRUMENT DEFINITIONS, RNT=NOTE CARD INFO, ROUT=OUTPUT BLOCK
01200	      EQUIVALENCE(M1,M(1)),(M2,M(2)),(M3,M(3)),(M4,M(4)),(M5,M(5)),(M6,M
01300	     1(6)),(M7,M(7)),(M8,M(8)),(L1,L(1)),(L2,L(2)),(L3,L(3)),(L4,L(4)),(  
01400	     2 L5,L(5)),(L6,L(6)),(L7,L(7)),(L8,L(8)),(AMP,XIN1),(FREQ,XIN2)
01500		3 ,(I5,I(5)),(I6,I(6)),(I3,I(3)),(L9,L(9))
01600	CC      XNFUN=LFUNC-1      
01700	C     COMMON INITIALIZATION OF GENERATORS     
01800	CX    N1=I6+2   
01900	C I6 HAS POINTER TO CODE (IN INS ARRAY) FOR U.G. NOW TO BE PROCESSED.
02000	CX	N2=INS(N1-1)-1
02100	CX    DO 204 J1=N1,N2      
02200	CX    J2=J1-N1+1  
02300	CX	IF(INS(J1).GE.0)GO TO 201
02400	CX200  L(J2)=-INS(J1)
02500	CX    M(J2)=1     
02600	CX    GO TO 204     
02700	CX201  M(J2)=0     
02800	CX 	IF(INS(J1)-26262.GT.0)GO TO 203
02850	C ********* ABOVE TAKEN OUT
02900	C***** WHAT DOES THE BIG NUMBER DO?????
03000	C*** IT SEEMS TO BE JUST TO MAKE A FLAG. NOW CHANGED TO FIT INTO 16BITS.
03100	CX202  L(J2)=INS(J1)+I3-1 
03200	CX    GO TO 204     
03300	CX203  L(J2)=INS(J1)-26262  
03400	CX204  CONTINUE    
03500	CX    N3=INS(I6)  
03600	CX	IF(M1.LE.0)AMP=RNT(L1)      
03700	CX 	IF(M2.LE.0)FREQ=RNT(L2)     
03800	CX    J3=  N3 -100     
03900		CALL INITIT(J3)
04000	  	AMP=RNT(L1)      
04100	   	FREQ=RNT(L2)     
04200	      NSAM=I5   
04300	      NSAMX=NSAM-1
04400	C            OUT OSC AD2 RAI ENV STR AD3 AD4 MLT DIV RAH 
04500	      GO TO (101,102,103,104,105,106,107,108,109,110,111,112,113,114,
04600		1 115,116,117,118),J3     
04700	CC	IF(NGEN.EQ.14)CALL OPT(L,M,NSAM)
04800	C  FOLLOWING IS SUGGESTED HEADER FOR SUBROUTINE OPT
04900	C	SUBROUTINE OPT(L,M,NSAM)
05000	C	DIMENSION L(8),M(8)     
05100	C	COMMON /GENS/GENS(1)/LFUNC/LFUNC/NT/RNT(1)/ROUT/ROUT(1)
05200	 112  CALL OPT(J1,J2,J3)
05400	114	RETURN
05450	113	CALL REVERB
05475	C ADD REVERB SUBROUTINE ONLY WHEN WANTED.  IT NEEDS EXTRA MEMORY.
05500	117	RETURN
05600	C 117 WILL BE FOR 'INP', READING EXTERNAL SOUND FILES.
05700	
05800	C     UNIT GENERATORS    
05900	C     OUTPUT BOX  
06000	CX 101  IF(M1.LE.0)IN1=RNT(L1) 
06100	CX    DO 270 J3=0,NSAM-1
06200	CX    IF(M1.GT.0)IN1=ROUT(J3+L1)
06300	CX 265  J5=L2+J3  
06400	CX    ROUT(J5)=IN1+ROUT(J5)    
06500	CX 270  CONTINUE    
06600	CX    RETURN      
06700	101	CALL OUTP
06800	C CALLS 'FAIL' OUT BOX
06900		RETURN
07000	CC101   DO 270 K=0,NSAMX 
07100	      J5=L2+K
07200	270   ROUT(J5)=ROUT(J5)+ROUT(K+L1)
07300	      RETURN
07400	C OUTPUT=WHAT'S THERE ALREADY + WHAT'S COMING IN FROM THIS INST.
07500	C  THIS NEW FORM ASSUMES THE OUT BOX HAS ONLY 'Bn' AS INPUT.
07600	
07700	C     OSCILLATOR    L1,L2 = P or B   L3=B   L4=F or P   L5=P
07800	C			AMPL, TIME, OUTPUT,  FUNC,    5TH NO LONGER USED.
07900	C M1, M2 =1 = NT.  =0 = ROUT  (P=FIXED INPUT, B=DYNAMIC INPUT, F=FUNC.)
08000	102	CALL OSC
08100	C  CALL 'FAIL' OSC.
08200		RETURN
08300	CXX 102  SUM=RNT(L5)      
08400		CALL LOCGEN(M4,L4)
08500	C  FINDS POINTER TO FUNC NUM.  IF M4.EQ.1 THEN FNUM WAS IN INST DEF. 
08600	CC	IF(M1.LE.0)AMP=RNT(L1)      
08700	CC   	IF(M2.LE.0)FREQ=RNT(L2)     
08800	      DO 293 J3=0,NSAMX  
08900	      J4=INT(SUM)+L4     
09000	      F=GENS(J4)     
09100	C GENS(J4) IS IN FUNC STORAGE AREA.
09200		IF(M2.GT.0)GO TO 286
09300	      SUM=SUM+FREQ
09400	      GO TO 290     
09500	 286  J4=L2+J3
09600	      SUM=SUM+ROUT(J4)  
09700	290     IF(SUM.GE.XNFUN)SUM=SUM-XNFUN
09800	CC290     IF(SUM.GE.XNFUN)GO TO 287
09900	CC     IF(SUM.LT.0.0)GO TO 289
10000	 288  J5=L3+J3
10100		IF(M1.GT.0)GO TO 292
10200	      ROUT(J5)=AMP*F     
10300	      GO TO 293     
10400	C**********
10500	CC287    SUM=SUM-XNFUN
10600	CC     GO TO 288
10700	CC289    SUM=SUM+XNFUN
10800	CC     GO TO 288
10900	C******* ABOVE FOR FM (NEG. FREQ. TO OSCIL)
11000	 292  J6=L1+J3
11100	      ROUT(J5)=ROUT(J6)*F
11200	 293  CONTINUE    
11300	      RNT(L5)=SUM      
11400	C L5 POINTS TO NOTE ARRAY.     SAVE A POINTER.
11500	      RETURN      
11600	
11700	C 118 COS = CONTINUING, NEG. OSCILLATOR (FOR LEGATO)*** CAN'T PLAY CHORDS!!!
11800	118	L9=RNT(I3)
11900	C GET POINTER TO INS. NUM.
12000		SUM=COSP(L9)
12100	C ONLY 1 COS PER INSTRUMENT AT THIS TIME*****************
12200		GO TO 218
12300	C NOW JUMP AND ACT LIKE A 'NOS'.
12400	
12500	C 115 NEG OSCILLATOR  L1,L2 = P or B   L3=B   L4=F or P   L5=P
12600	C 'NOS'			 AMPL, TIME, OUTPUT,  FUNC,    5TH NO LONGER USED.
12700	C M1, M2 =1 = ROUT  =0 = PARM  (P=FIXED INPUT, B=DYNAMIC INPUT, F=FUNC.)
12800	115   SUM=RNT(L5)      
12900	218	CALL LOCGEN(M4,L4)
13000	C  FINDS POINTER TO FUNC NUM.  IF M4.EQ.1 THEN FNUM WAS IN INST DEF. 
13100	CC	IF(M1.LE.0)AMP=RNT(L1)      
13200	CC   	IF(M2.LE.0)FREQ=RNT(L2)     
13300	      DO 215 L7=0,NSAMX  
13400	      J4=INT(SUM)+L4     
13500	      F=GENS(J4)     
13600	C GENS(J4) IS IN FUNC STORAGE AREA.
13700		IF(M2.GT.0)GO TO 915
13800	      SUM=SUM+FREQ
13900	      GO TO 315
14000	915   J4=L2+L7
14100	      SUM=SUM+ROUT(J4)  
14200	315     IF(SUM.GE.XNFUN)GO TO 415
14300	       IF(SUM.LT.0.0)GO TO 615
14400	715   J5=L3+L7
14500		IF(M1.GT.0)GO TO 815
14600	      ROUT(J5)=AMP*F     
14700	      GO TO 215     
14800	C**********
14900	415    SUM=SUM-XNFUN
15000	       GO TO 715
15100	615    SUM=SUM+XNFUN
15200	       GO TO 715
15300	C******* ABOVE FOR FM (NEG. FREQ. TO OSCIL)
15400	815   J6=L1+L7
15500	      ROUT(J5)=ROUT(J6)*F
15600	215   CONTINUE    
15700		IF(J3.EQ.18)GO TO 318
15800	C JUMP IF THIS IS 'COS' BEING PROCESSED
15900	      RNT(L5)=SUM      
16000	C L5 POINTS TO NOTE ARRAY.     SAVE A POINTER.
16100	      RETURN      
16200	318	COSP(L9)=SUM
16300	C SAVE POINTER FOR INST. L9
16400		RETURN
16500	
16600	C     ADD TWO BOX 
16700	C LOOK AT NT ARRAY FOR FIXED VALUES, LOOK AT ROUT FOR CHANGING VALS.
16800	CC103	IF(M1.LE.0)XIN1=RNT(L1)   
16900	CC      IF(M2.LE.0)XIN2=RNT(L2)   
17000	103      DO 258 J3=0,NSAMX    
17100		IF(M1.GT.0)XIN1=ROUT(J3+L1)
17200	    	IF(M2.GT.0)XIN2=ROUT(L2+J3)
17300	      ROUT(J3+L3)=XIN1+XIN2      
17400	 258  CONTINUE    
17500	      RETURN      
17600	
17700	C 116  SUBTRACT
17800	CC116	IF(M1.LE.0)XIN1=RNT(L1)   
17900	CC      IF(M2.LE.0)XIN2=RNT(L2)   
18000	116      DO 1016 J3=0,NSAMX    
18100		IF(M1.GT.0)XIN1=ROUT(J3+L1)
18200	    	IF(M2.GT.0)XIN2=ROUT(L2+J3)
18300	      ROUT(J3+L3)=XIN1-XIN2      
18400	 1016  CONTINUE    
18500	      RETURN      
18600	
18700	C RANDOM INTERPOLATING GENERATOR   RAI Px Py Bn Pq Pr Ps; OR RAI L1 L2 L3 L4 L5 L6;
18800	C M1=0=Pn   M1=1=Bn
18900	 104  SUM=RNT(L4)      
19000		  RN1=RNT(L5)  
19100	      RN3=RNT(L6)  
19200	CC	IF(M1.LE.0)XIN1=RNT(L1)     
19300	CC   	IF(M2.LE.0)XIN2=RNT(L2)     
19400		IF(SUM.NE.0)GO TO 313
19500		CALL RNDM(RN1)
19600		CALL RNDM(RN3)
19700	C INIT THE RANDOM NUMBERS.
19800	313      DO 340 J3=0,NSAMX    
19900		IF(M1.GT.0)XIN1=ROUT(J3+L1)     
20000	    	IF(M2.GT.0)XIN2=ROUT(J3+L2)     
20100	      IF(XNFUN.GT.SUM)GO TO 320
20200	CC    IF(SUM-XNFUN.LT.0)GO TO 320
20300	      SUM=SUM-XNFUN      
20400		CALL RNDM(RN4)
20500	304      RN2=RN4-RN3 
20600	      RN1=RN3     
20700	      RN3=RN4     
20800	      GO TO 321     
20900	 320  RN2=RN3-RN1 
21000	321   ROUT(J3+L3)=XIN1*(RN1+(RN2*SUM)/XNFUN)   
21100	      SUM=SUM+XIN2
21200	 340  CONTINUE    
21300	      RNT(L4)=SUM       
21400	      RNT(L5)=RN1  
21500	      RNT(L6)=RN3  
21600	      RETURN      
21700	
21800	C     ENVELOPE GENERATOR   ENV PorB, ForP, B,  P,   P,   P,  P,  P;
21900	C			       AMPL FUNC OUT ATCK STDY DCAY FLAG STOR
22000	C FLAG=1=NO CONTINUATION, REINITS FOR EACH NOTE AND CAN PLAY ON TOP OF SELF.
22100	C FLAG=0=INIT CONTINUATION FOR SEVERAL NOTES UNDER 1 ENV.
22200	C -1=CONTINUATION	(USE DIFFERENT INS. NUMS FOR CHORDS!!)
22300	105	L9=RNT(I3)
22400	C  GET INS. NUM.
22500		ENVX=RNT(L7)
22600		IF(ENVX)805,605,905
22700	905	SUM=RNT(L8)
22800		GO TO 705
22900	805	SUM=ENVP(L9)      
23000		GO TO 705
23100	605	SUM=0
23200		RNT(L7)=-1.
23300	705	CALL LOCGEN(M2,L2)
23400	C  FINDS POINTER TO FUNC NUM.  IF M2.EQ.1 THEN FNUM WAS IN INST DEF. 
23500	      XIN4=RNT(L4)
23600	      XIN5=RNT(L5)
23700	      XIN6=RNT(L6)
23800	      XIN5=PINCR/(PINCR/XIN5 - PINCR/XIN4 -PINCR/XIN6 )
23900	C XIN5 HAS INCR. VALUE OF STEADY STATE. (IT WAS TOTAL DUR. BEFORE.)
24000	C THESE 3 PARAMS ARE ATTACK DUR, TOTAL DUR, DECAY DUR.
24100	C  STEADY STATE TIME IS COMPUTED
24200	CC	IF(M1.LE.0)AMP =RNT(L1)     
24300	CX 	IF(M4.LE.0)XIN4=FLOAT(RNT(L4))*SFI     
24400	CX 	IF(M5.LE.0)XIN5=FLOAT(RNT(L5))*SFI     
24500	CX 	IF(M6.LE.0)XIN6=FLOAT(RNT(L6))*SFI     
24600	      XIN4=XIN4/4.
24700	      XIN5=XIN5/4.
24800	      XIN6=XIN6/4.
24900	CC 387  X1=XNFUN/4. 
25000	CC    X2=X1+X1    
25100	CC    X3=X2+X1    
25200		X1=128.
25300		X2=256.
25400		X3=384.
25500	C THESE NUMBERS BASED ON USING 3/4 OF 512 ARRAY.
25600	      DO 205 J3=0,NSAMX    
25700	      J4=INT(SUM)+L2     
25800	      F=GENS(J4)     
25900		IF(M1.GT.0)AMP =ROUT(J3+L1)      
26000	   	IF(SUM.GE.384.)SUM=0
26100	C FOR WRAP-AROUND
26200	   	IF(SUM.GE.128.)GO TO 305
26300	C JUMP IF ATTACK BOUNDRY IS PASSED.
26400	CC 	IF(SUM-X3.GE.0)SUM=SUM-X3
26500	CC 	IF(SUM-X1.GT.0)GO TO 305
26600	CX  	IF(M4.GT.0)XIN4=FLOAT(ROUT(J3+L4))      
26700	      SUM=SUM+XIN4       
26800	      GO TO 405    
26900	305	IF(SUM.GE.256.)GO TO 505
27000	C JUMP IF STEADY STATE BOUNDRY IS PASSED.
27100	CC305	IF(SUM-X2.GT.0)GO TO 505
27200	CX  	IF(M5.GT.0)XIN5=FLOAT(ROUT(J3+L5))      
27300	      SUM=SUM+XIN5       
27400	      GO TO 405    
27500	CX505	IF(M6.GT.0)XIN6=FLOAT(ROUT(J3+L6))      
27600	505   SUM=SUM+XIN6       
27700	 405  J7=L3+J3
27800	      ROUT(J7)=AMP*F     
27900	 205  CONTINUE   
28000		IF(ENVX.LE.0)GO TO 1005
28100		RNT(L8)=SUM
28200		RETURN
28300	1005  ENVP(L9)=SUM       
28400	      RETURN     
28500	
28600	C     STEREO OUTPUT BOX  L1,L2 = B       L3=B1
28700	C IT IS ASSUMED ALL INPUTS ARE 'B' TYPE.
28800	106   NSSAM=2*NSAM       
28900	C  6/29/70  L.C.SMITH
29000	      ICT=0
29100	      DO 206 J3=1,NSSAM,2  
29200	      J4=L1+ICT
29300	      XIN1=ROUT(J4)  
29400	 306  J5=L3+J3-1 
29500	      ROUT(J5)=XIN1+ROUT(J5)    
29600	506   J4=L2+ICT
29700	      XIN2=ROUT(J4)  
29800	 406  J5=L3+J3   
29900	      ROUT(J5)=XIN2+ROUT(J5)    
30000	 206  ICT=ICT+1  
30100	      RETURN     
30200	C     STEREO OUTPUT BOX  
30300	CX106	IF(M1.GT.0)GO TO 501
30400	CCC 106  IF(M1)500,500,501  
30500	CX 500  IN1=I(L1)  
30600	CX501	IF(M2.GT.0)GO TO 503
30700	CCC 501  IF(M2)502,502,503  
30800	CX 502  IN2=I(L2)  
30900	CX 503  NSSAM=2*NSAM       
31000	C  6/29/70  L.C.SMITH
31100	CX      ICT=0
31200	CX      DO 206 J3=1,NSSAM,2  
31300	CX	IF(M1.LE.0)GO TO 306
31400	CCC   IF(M1)306,306,504  
31500	CC*** 504  J4=L1+J3-1 
31600	CX504   J4=L1+ICT
31700	CX      IN1=I(J4)  
31800	CX 306  J5=L3+J3-1 
31900	CX      I(J5)=IN1+I(J5)    
32000	CX	IF(M2.LE.0)GO TO 406
32100	CCC   IF(M2)406,406,506  
32200	CC*** 506  J4=L2+J3-1 
32300	CX506   J4=L2+ICT
32400	CX      IN2=I(J4)  
32500	CX 406  J5=L3+J3   
32600	CX      I(J5)=IN2+I(J5)    
32700	CX 206  ICT=ICT+1  
32800	CX      RETURN     
32900	
33000	C     ADD 3 BOX  
33100	CC107	IF(M1.LE.0)XIN1=RNT(L1)  
33200	CC   	IF(M2.LE.0)XIN2=RNT(L2)  
33300	107   	IF(M3.LE.0)XIN3=RNT(L3)  
33400	      DO 780 J3=0,NSAMX    
33500		IF(M1.GT.0)XIN1=ROUT(L1+J3)
33600	   	IF(M2.GT.0)XIN2=ROUT(L2+J3)
33700	   	IF(M3.GT.0)XIN3=ROUT(L3+J3)
33800	      ROUT(J3+L4)=XIN1+XIN2+XIN3  
33900	 780  CONTINUE   
34000	      RETURN     
34100	
34200	C     ADD 4 BOX  
34300	CC 108  IF(M1.LE.0)XIN1=RNT(L1)  
34400	CC      IF(M2.LE.0)XIN2=RNT(L2)  
34500	108      IF(M3.LE.0)XIN3=RNT(L3)  
34600	      IF(M4.LE.0)XIN4=RNT(L4)  
34700	      DO 880 K=0,NSAMX    
34800	      IF(M1.GT.0)XIN1=ROUT(L1+K)  
34900	 859  IF(M2.GT.0)XIN2=ROUT(L2+K)
35000	      IF(M3.GT.0)XIN3=ROUT(L3+K)
35100	 863  IF(M4.GT.0)XIN4=ROUT(L4+K)
35200	      ROUT(L5+K)=XIN1+XIN2+XIN3+XIN4      
35300	880   CONTINUE   
35400	      RETURN     
35500	
35600	C     MULTIPLIER 
35700	CC109   IF(M1.LE.0)XIN1=RNT(L1)
35800	CC      IF(M2.LE.0)XIN2=RNT(L2)
35900	109      DO 908 J3=0,NSAMX
36000	      IF(M1.GT.0)XIN1=ROUT(J3+L1)
36100	      IF(M2.GT.0)XIN2=ROUT(J3+L2)
36200	      ROUT(J3+L3)=XIN1*XIN2
36300	 908  CONTINUE   
36400	      RETURN     
36500	
36600	C 110 DIVIDER
36700	CC110   IF(M1.LE.0)XIN1=RNT(L1)
36800	CC      IF(M2.LE.0)XIN2=RNT(L2)
36900	110      DO 1010 J3=0,NSAMX
37000	      IF(M1.GT.0)XIN1=ROUT(J3+L1)
37100	      IF(M2.GT.0)XIN2=ROUT(J3+L2)
37200	1010      ROUT(J3+L3)=XIN1/XIN2
37300	      RETURN     
37400	
37500	
37600	C     SET NEW FUNCTION IN OSC OR ENV     
37700	CC 110  ILOC=N1+6  
37800	CC      IF(INS(N1+1).EQ.105) ILOC=N1+4 
37900	CC      JN1=I(3)+INS(N1)-1   
38000	CC      IIN1=RNT(JN1)
38100	CC     IF(IIN1.GT.0) INS(ILOC)=-(IIN1-1)*LFUNC-1    
38200	C 'SET' NO LONGER NEEDED!!!!  NOW 110 CAN BE USED FOR SOMETHING ELSE.
38300	
38400	C     RANDOM AND HOLD GENERATOR     RAH Px Py Bn Pq Pr; OR RAH L1 L2 L3 L4 L5;
38500	C M1=0=Pn   M1=1=Bn
38600	 111  SUM=RNT(L4)       
38700	CC      IF(M1.LE.0)XIN1=RNT(L1)      
38800	CC      IF(M2.LE.0)XIN2=RNT(L2)      
38900	 913  RN=RNT(L5)  
39000		IF(SUM.EQ.0)CALL RNDM(RN)
39100	C TO INIT RANDOM NUMB.  (COULD THIS EVER LOSE?)
39200	      DO 940 J3=0,NSAMX    
39300	      IF(M1.GT.0) XIN1=ROUT(J3+L1)      
39400	      IF(M2.GT.0) XIN2=ROUT(J3+L2)      
39500	      IF(XNFUN.GT.SUM)GO TO 920
39600	CC    IF(SUM-XNFUN.LT.0)GO TO 920
39700	      SUM=SUM-XNFUN      
39800		CALL RNDM(RN)
39900	920   ROUT(J3+L3)=XIN1*RN 
40000	      SUM=SUM+XIN2       
40100	 940  CONTINUE   
40200	      RNT(L4)=SUM       
40300	      RNT(L5)=RN  
40400	      RETURN     
40500	
60000	      END
60100	
60200		SUBROUTINE RNDM(X)
60300		X=2.*RAN(X)-1.
60400	C SENDS BACK NUMBER BETWEEN -1 AND +1
60500		END
60600	
60700		SUBROUTINE LOCGEN(M,L)
60800		COMMON /NT/RNT(1) /LOCG/LOCG(1)
60900		IF(M.EQ.0)L=LOCG(INT(RNT(L)))
61000	C GET POINTER TO START OF FUNC. ARRAY
61100		END
61200	
61300	 	SUBROUTINE OPT(L,M,NSAM)
61400	 	DIMENSION L(1),M(1)     
61500	 	COMMON /GENS/GENS(1)/LFUNC/LFUNC,XNFUN
61600		1/NT/RNT(1)/ROUT/ROUT(1)
61700	C THIS IS A DUMMY ROUTINE     OPT Pm Pn Bn;  doubles value of Bn
61800		J1=L(3)
61900	C L(3) MEANS LOOK AT 3RD FIELD OF 'OPT'
62000		J2=J1+NSAM-1
62100		DO 1 K=J1,J2   
62200	1	ROUT(K)=ROUT(K)*2
62300		RETURN
62400		END